package helper.base.math

import helper.base.A2LHM
import helper.base.math.MathHelper.Sign.Obj.aDivisionSign
import helper.base.math.MathHelper.Sign.Obj.aMultipleSign
import kotlin.math.max
import kotlin.random.Random

object MathHelper {
    fun Int.modifiedMinus(
        int: Int,
    ): Int {
        return max(
            0,
            this - int,
        )
    }

    //可以放弃
    fun getRandomStringWithLeftTime(
        stringDistributionProbabilityMap: Map<String, Double>,
        leftTime: Int = 1,
    ): String? {
        val random = Random.nextDouble() * stringDistributionProbabilityMap.values.sum() * leftTime
        var cumulativeProbability = 0.0

        for ((string, prob) in stringDistributionProbabilityMap) {
            cumulativeProbability += prob
            if (random <= cumulativeProbability) {
                return string
            }
        }
        return null
    }

    /**
     * 函数名解释：
     * - `print`: 通常指输出或显示信息，在此函数中意味着返回一个格式化后的字符串，而不是直接打印。
     * - `Double`: 表示函数处理的数据类型为双精度浮点数（Double），适用于表示带有小数的数字。
     * - `WithoutTrailingZeros`: 指去除数字小数点后面不必要的零，使数值表示更加简洁。
     *
     * 总的来说，`printDoubleWithoutTrailingZeros` 函数的目的是接受一个Double类型的数值，
     * 去除其小数点后不必要的尾随零，并将处理后的结果作为字符串返回。这个处理过程使得数字在显示或记录时看起来更加简洁，
     * 尤其是在不需要展示精确到非常小的数值时。
     */
    fun printDoubleWithoutTrailingZeros(value: Double): String {
        // 使用 if 表达式来判断 value 是否为整数
        return if (value % 1 == 0.0) {
            // 如果 value 除以 1 的余数为 0，说明它是一个整数
            // 这时，将 value 转换为 Long 类型（去除小数部分），然后转换为字符串返回
            // 例子: 如果 value = 100.0，结果将是 "100"
            value.toLong().toString()
        } else {
            // 如果 value 不是整数，即小数部分不为 0
            // 首先将 value 转换为字符串
            // 然后使用 trimEnd('0') 去除字符串末尾的所有 '0'
            // 接着使用 trimEnd('.') 去除可能因为去零操作后留下的末尾小数点
            // 最后返回处理后的字符串
            // 例子: 如果 value = 100.5000，结果将是 "100.5"
            // 另一个例子: 如果 value = 150.0，结果将是 "150"
            value.toString().trimEnd('0').trimEnd('.')
        }
    }


    class Sign(
        val name: String
    ) {
        companion object {
            fun getSign(
                name: String
            ): Sign {
                return Sign(name)
            }
        }

        object Obj {
            val aMultipleSign = getSign("*")
            val aDivisionSign = getSign("/")
        }
    }

    object ToMathLStringHelper {
        fun Double.toPreSymbolString(
            preSymbol: Sign
        ): String {
            if (preSymbol == aMultipleSign || preSymbol == aDivisionSign) {
                if (this == 1.0) {
                    return ""
                }
            }
            return "${preSymbol.name}${this}"
        }
    }

    object MapListMerger {
        fun <E> getCombinedProductMap(
            inputMapList: List<A2LHM<E, Double>>,
            deepCopyFunction: (List<E>) -> List<E> = { list ->
                ArrayList(list)
            },
        ): A2LHM<List<E>, Double> {
            val resultMergedMap = A2LHM<List<E>, Double>()

            // 剔除空的 A2LHM
            val filteredInputMapList = inputMapList.filter { it.isNotEmpty() }

            fun getProductCombinations(idx: Int, keys: MutableList<E>, value: Double) {
                if (idx == filteredInputMapList.size) {
                    resultMergedMap[deepCopyFunction(keys)] = value  // 使用深拷贝函数
                    return
                }

                for ((key, valMultiplier) in filteredInputMapList[idx]) {
                    keys.add(key)
                    getProductCombinations(idx + 1, keys, value * valMultiplier)
                    keys.removeAt(keys.lastIndex)
                }
            }

            getProductCombinations(0, mutableListOf(), 1.0)
            return resultMergedMap
        }
    }
}